package com.cxyjy.travelguide.controller;

import com.alibaba.dashscope.app.*;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
    AI问答接口
     必选
     * @param text: 用户提的问题
     可选
     * @param message: 历史消息
     * @param pipelineIds：使用的知识库ID，列表，里面字符串，用逗号隔开，上限5
     * @param tags：查询时所用的标签
     * @param fileIds：查询时使用的文档ID，上限100

     * @return json
        "code": 标识码，200表示成功
        "msg": 返回信息
        "data": 返回数据内容
        {
        "requestId": 请求Id
        "text": 回答内容
        "inputTokens": 输入消耗token
        "outputTokens": 输出消耗token
        "messages": 历史对话记录，包含本次最新一轮问答，格式为List<Map<String,String>>
            例如"messages": [
            {
                "role": "system",
                "content": "你是一位为用户解决行程规划难题的助手，会积极使用知识库中的相关知识，为用户合理安排出行计划，会考虑到景点开放时间、相应城市对应时间的交通状况等因素，周到地为用户提供回复。"
            },
            {
                "role": "user",
                "content": "你是谁"
            },
            {
                "role": "assistant",
                "content": "你好！我是你的行程规划助手，专门帮你解决出行难题的。无论是景点推荐、路线安排，还是交通、时间规划，我都会根据最新的信息为你提供周到的建议。需要我帮你规划什么？"
            }]
            }
 */

@RestController
@RequestMapping("/v1")
public class QwenController {

    @Value("${dashscope.api-key}")
    private String apiKey;


    @Value("${dashscope.app-id}")
    private String appId;

//    private static final String DASHSCOPE_API_URL = "https://dashscope.aliyuncs.com/api/v1/applications/%s/calls";
    private static final ObjectMapper objectMapper = new ObjectMapper();
//    @Value("${DASHSCOPE_API_KEY}")
//    private final String apiKey=System.getenv("DASHSCOPE_API_KEY");
    //上方使用系统环境变量定义的api-key，下方使用自定义api-key

    @PostMapping("/AIQA-chat")
    public String chatCompletion(@RequestBody Map<String, Object> request) {

        try {
            // 参数验证逻辑...
            // 消息处理逻辑...
            //处理合并历史消息
            Map <String,String> newmessage=new HashMap<>();
            Object messages=request.get("message");

            List<Map<String,String>> message=new ArrayList<>();
            List<Message> originmessages = new ArrayList<>();
            try {
                // 安全转换：将未知类型的 rawMessages 转换为 List<Message>
                if (messages != null) {
                    message = objectMapper.convertValue(
                            messages,
                            new TypeReference<List<Map<String, String>>>() {
                            }
                    );
                    originmessages= objectMapper.convertValue(
                            messages,
                            new TypeReference<List<Message>>() {
                            }
                    );
                }
            } catch (IllegalArgumentException e) {
                    // 转换失败时的处理（例如日志记录）
                    System.err.println("消息格式不合法，请使用默认列表");
                    ObjectNode response = objectMapper.createObjectNode();
                    response.put("code", 304); //
                    response.put("msg", e.getMessage()+"  可能错误原因：传入message字段格式不正确");
                    ObjectNode data = objectMapper.createObjectNode();
                    response.set("data", data);
                    return response.toString();
                }

//            System.out.println(message);
//            System.out.println(originmessages);
            if (originmessages.isEmpty())
            {
                originmessages = new ArrayList<>();
                originmessages.add(Message.builder().role("system").content("你是一位为用户解决行程规划难题的助手，会积极使用知识库中的相关知识，为用户合理安排出行计划，会考虑到景点开放时间、相应城市对应时间的交通状况等因素，周到地为用户提供回复。").build());
                message=new ArrayList<>();
                newmessage.put("role", "system");
                newmessage.put("content", "你是一位为用户解决行程规划难题的助手，会积极使用知识库中的相关知识，为用户合理安排出行计划，会考虑到景点开放时间、相应城市对应时间的交通状况等因素，周到地为用户提供回复。");
                message.add(newmessage);
            }
            String text = (String) request.get("text");
            if (text.isEmpty()){
                ObjectNode response = objectMapper.createObjectNode();
                response.put("code", 303); //
                response.put("msg", "调用失败，text的值不能为空！");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            }
//            System.out.println(message);
            originmessages.add(Message.builder().role("user").content(text).build());
//            System.out.println(message);
            newmessage=new HashMap<>();
            newmessage.put("role", "user");
            newmessage.put("content", text);
            message.add(newmessage);
//            System.out.println(originmessages);

            //添加可选参数
            List<String> pipelineIds=new ArrayList<>();
            try {
                // 安全转换：将未知类型的 rawMessages 转换为 List<Message>
                if (request.get("pipelineIds") != null) {
                    pipelineIds = objectMapper.convertValue(
                            request.get("pipelineIds"),
                            new TypeReference<List<String>>() {
                            }
                    );
                }
            } catch (IllegalArgumentException e) {
                // 转换失败时的处理（例如日志记录）
                System.err.println("消息格式不合法，请使用默认列表");
                ObjectNode response = objectMapper.createObjectNode();
                response.put("code", 304); //
                response.put("msg", e.getMessage()+"  可能错误原因：传入pipelineIds字段格式不正确");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            }

            List<String> fileIds=new ArrayList<>();
            try {
                // 安全转换：将未知类型的 rawMessages 转换为 List<Message>
                if (request.get("fileIds") != null) {
                    fileIds = objectMapper.convertValue(
                            request.get("fileIds"),
                            new TypeReference<List<String>>() {
                            }
                    );
                }
            } catch (IllegalArgumentException e) {
                // 转换失败时的处理（例如日志记录）
                System.err.println("消息格式不合法，请使用默认列表");
                ObjectNode response = objectMapper.createObjectNode();
                response.put("code", 304); //
                response.put("msg", e.getMessage()+"  可能错误原因：传入fileIds字段格式不正确");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            }

            List<String> tags=new ArrayList<>();
            try {
                // 安全转换：将未知类型的 rawMessages 转换为 List<Message>
                if (request.get("tags") != null) {
                    tags = objectMapper.convertValue(
                            request.get("tags"),
                            new TypeReference<List<String>>() {
                            }
                    );
                }
            } catch (IllegalArgumentException e) {
                // 转换失败时的处理（例如日志记录）
                System.err.println("消息格式不合法，请使用默认列表");
                ObjectNode response = objectMapper.createObjectNode();
                response.put("code", 304); //
                response.put("msg", e.getMessage()+"  可能错误原因：传入tags字段格式不正确");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            }
//            System.out.println(pipelineIds);
//            System.out.println(tags);
            //组装大模型输入参数
            ApplicationParam param = ApplicationParam.builder()
                    // 若没有配置环境变量，可用百炼API Key将下行替换为：.apiKey("sk-xxx")。但不建议在生产环境中直接将API Key硬编码到代码中，以减少API Key泄露风险。
                    .apiKey(apiKey)
                    .appId(appId) // 替换为实际的应用ID
                    .messages(originmessages)
//                    .prompt((String) request.get("text"))
                    .hasThoughts(true)
                    .ragOptions(RagOptions.builder()
                            .pipelineIds(pipelineIds)
                            .tags(tags)
                            .fileIds(fileIds)
                            .build())
                    .build();
            //发送请求
            Application application = new Application();
            ObjectNode response = objectMapper.createObjectNode();
            try  {
                ApplicationResult result;
                result = application.call(param);
                return handleApiResponse(result,message);
            }catch (ApiException  e) {
                response.put("code", 302); //
                response.put("msg", "调用失败，应用Api或api-key不正确");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            } catch (NoApiKeyException e) {
                response.put("code", 302); //
                response.put("msg", "调用失败，没有Api-key");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            } catch (InputRequiredException e) {
                response.put("code", 303); //
                response.put("msg", "调用失败，输入缺少必要内容！");
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            } catch (Exception e) {
                response.put("code", 300); //
                response.put("msg", "调用失败"+e.getMessage());
                ObjectNode data = objectMapper.createObjectNode();
                response.set("data", data);
                return response.toString();
            }
        } catch (Exception e) {
            ObjectNode response = objectMapper.createObjectNode();
            response.put("code", 301); //
            response.put("msg", e.getMessage()+"  可能错误原因：未传入必选text字段");
            ObjectNode data = objectMapper.createObjectNode();
            response.set("data", data);
            return response.toString();
        }
//        return null;
    }

    //处理返回结果
    private static String handleApiResponse(ApplicationResult result,List<Map<String,String>> originmessages) throws IOException {
        ObjectNode response = objectMapper.createObjectNode();
        response.put("code", 200); // 假设成功场景
        response.put("msg", "调用成功");
//        System.out.println(result);
        // 2. 创建 data 对象并填充字段
        ObjectNode data = objectMapper.createObjectNode();
        data.put("requestId", result.getRequestId()); // 直接提取 requestId

        String text=result.getOutput().getText();
        // 提取 output.text（需判空）
        if (result.getOutput() != null) {
            data.put("text", text);
        } else {
            data.putNull("text"); // 或 data.put("text", "")
        }

        // 提取 usage.models[0] 的 input/outputTokens（需判空）
        if (result.getUsage() != null
                && !result.getUsage().getModels().isEmpty()) {
            ApplicationUsage.ModelUsage model = result.getUsage().getModels().get(0);
            data.put("inputTokens", model.getInputTokens());
            data.put("outputTokens", model.getOutputTokens());
        } else {
            // 若 models 为空，设置默认值（根据需求调整）
            data.put("inputTokens", 0);
            data.put("outputTokens", 0);
        }
        Map<String,String> newmessage=new HashMap<>();
        newmessage.put("role", "assistant");
        newmessage.put("content", text);
        originmessages.add(newmessage);
        JsonNode messagesNode = objectMapper.convertValue(originmessages, JsonNode.class);
        data.set("messages", messagesNode);
        // 3. 将 data 加入外层响应
        response.set("data", data);

        // 4. 返回 JSON 字符串
        return response.toString();

    }


}
